/*
 * SilverFoxServer: massive multiplayer game server for Flash, ...
 * VERSION:3.0
 * PUBLISH DATE:2015-9-2 
 * GITHUB:github.com/wdmir/521266750_qq_com
 * UPDATES AND DOCUMENTATION AT: http://www.silverfoxserver.net
 * COPYRIGHT 2009-2015 SilverFoxServer.NET. All rights reserved.
 * MAIL:521266750@qq.com
 */
package net.silverfoxserver.ext.handler;

import System.Xml.XmlDocument;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import net.silverfoxserver.core.array.QueueMethod;
import net.silverfoxserver.core.log.Log;
import net.silverfoxserver.core.protocol.ClientAction;
import net.silverfoxserver.core.service.IoHandler;
import net.silverfoxserver.core.socket.AppSession;
import net.silverfoxserver.core.socket.SessionMessage;
import net.silverfoxserver.core.socket.SocketConnector;
import net.silverfoxserver.ext.Globals;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jdom2.Attribute;


/**
 *
 * @author FUX
 */
public class GameServerHandler implements IoHandler{
    
    
    //static final ChannelGroup channels = new DefaultChannelGroup();
    
    private String _connectServerName;
    
    public GameServerHandler(String value)
    {
        _connectServerName = value;
    
    }

    
    public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e){
        if (e instanceof ChannelStateEvent) {
            System.err.println(e);
        }
        //super.handleUpstream(ctx, e);
    }

    
    public void sessionCreated(ChannelHandlerContext ctx, ChannelStateEvent e) {
        // Get the SslHandler in the current pipeline.
        // We added it in SecureChatPipelineFactory.
        //final SslHandler sslHandler = ctx.getPipeline().get(SslHandler.class);

        // Get notified when SSL handshake is done.
       // ChannelFuture handshakeFuture = sslHandler.handshake();
        //handshakeFuture.addListener(new Greeter(sslHandler));
    }

    
    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
        // Unregister the channel from the global channel list
        // so the channel does not receive messages anymore.
        //channels.remove(e.getChannel());
    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e,XmlDocument d) {

       
        MessageEvent s = e;        
        
      // Convert to a String first.        
        XmlDocument doc = d;//new XmlDocument();
        //doc.LoadXml((String)message);
        
        //如缺少属性字段，访问会报错，并导致和游戏逻辑服务器连接断开的严重后果
        Attribute actionAtt = doc.getDocumentElement().getChildren().get(0).getAttribute("action");
        Attribute sAtt      = doc.getDocumentElement().getChildren().get(0).getAttribute("s");
        Attribute fromGateAtt = doc.getDocumentElement().getChildren().get(0).getAttribute("fromGate");
        Attribute serverAtt = doc.getDocumentElement().getChildren().get(0).getAttribute("server");
        
        if(null == actionAtt)
        {
            Log.WriteStrByWarn("doc body element do not have action attribute: " + doc.toString());
            return;
        }
        
        if(null == sAtt)
        {
            Log.WriteStrByWarn("doc body element do not have s attribute: " + doc.toString());
            return;
        }
        
        if(null == fromGateAtt)
        {
            Log.WriteStrByWarn("doc body element do not have fromGate attribute: " + doc.toString());
            return;
        }
        
        if(null == serverAtt)
        {
            Log.WriteStrByWarn("doc body element do not have server attribute: " + doc.toString());
            return;
        }
        
        //String cAction = doc.DocumentElement.ChildNodes[0].Attributes["action"].Value;
        
        String cAction = actionAtt.getValue();
        
        //InetSocketAddress remoteAddress = (InetSocketAddress)s.getChannel().getRemoteAddress();
	//String strIpPort = remoteAddress.getAddress().getHostAddress() + ":" + String.valueOf(remoteAddress.getPort());
        
        String strIpPort = sAtt.getValue();
        
        
        AppSession c = Globals.mainWindowModel.acceptor.getSession(strIpPort);
        
        String msgOri = (String)e.getMessage();
        msgOri += "\0";
        this.Send(c, msgOri.getBytes(Charset.forName("utf-8")));
        
//
//        //create item
          //SessionMessage item = new SessionMessage(e, doc, false, true);
//
//        //save
           //DdzLPU.getInstance().getmsgList().Opp(QueueMethod.Add, item);
//
//        //
            if (cAction.equals(ClientAction.heartBeat))
            {
                    //不打印
            }
            else
            {
                    //log
                    Log.WriteStrByRecv(cAction, strIpPort);
            }

        
       
    }
    

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
        e.getCause().printStackTrace();
        e.getChannel().close();
    }

    @Override
    public void sessionOpened() {
       //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void sessionClosed(ChannelHandlerContext ctx, ChannelStateEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        
        //DdzLogic.getInstance().RCConnector.retryConnect();
        
         SocketConnector s = Globals.mainWindowModel.findConnectServer(_connectServerName);
        
        if(s != null){
        
            s.retryConnect();
        
        }
       
       
    }
    
    public void Send(AppSession session, byte[] value)
    {
        //
        if (null == session || null == value)
        {
            System.out.println("Send null?");
            return;
        }

        //session.Send(message, 0, message.length);

        ChannelBuffer buffer = ChannelBuffers.buffer(value.length);
        buffer.writeBytes(value);
        session.getChannel().write(buffer);

    }
}
